/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside.ui;

import java.io.File;
import java.io.IOException;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import phoside.PhosideInit;
import phoside.PhosphoProteins;
import phoside.PhosphoProteinsImpl;

import phoside.disorder.DisorderInfoBatchWriter;
import phoside.disorder.DisorderInfoBatchWriterFasta;
import phoside.disorder.DisorderPredictorVSL2;
import phoside.disorder.DisorderUtil;

import phoside.io.ProteinsReader;
import phoside.io.fasta.PhosphoReaderFromFastaWithSitesInSequence;
import phoside.io.xml.PhosideXmlProteinsReader;
import phoside.io.xml.PhosphoProteinFieldValueFormatter;

import phoside.model.PhosideModel;

import phoside.ui.task.DisorderReadTask;
import phoside.ui.task.DisorderPredictionTask;
import phoside.ui.task.PhosideTrainTask;
import phoside.ui.task.SerializeTask;
import phoside.ui.task.ProteinsReadTask;

import phoside.util.FileExtensionsFilter;
import phoside.util.FilePathParser;
import phoside.util.StaticFinalValues;

/**
 *
 * @author gjj
 */
public class PhosideTrainDialog extends javax.swing.JDialog {

    /** Creates new form PhosideTrainDialog */
    public PhosideTrainDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        fileTypeTabbedPane = new javax.swing.JTabbedPane();
        xmlPanel = new javax.swing.JPanel();
        javax.swing.JPanel xmlFilePanel = new javax.swing.JPanel();
        javax.swing.JPanel trainXmlFilePanel = new javax.swing.JPanel();
        trainXmlFileTextField = new javax.swing.JTextField();
        javax.swing.JButton trainXmlFileButton = new javax.swing.JButton();
        fastaPanel = new javax.swing.JPanel();
        javax.swing.JPanel fastaFilePanel = new javax.swing.JPanel();
        javax.swing.JPanel trainFastaFilePanel = new javax.swing.JPanel();
        trainFastaFileTextField = new javax.swing.JTextField();
        javax.swing.JButton trainFastaFileButton = new javax.swing.JButton();
        disorderPanel = new javax.swing.JPanel();
        disorderFileCheckBox = new javax.swing.JCheckBox();
        disordeFileTextField = new javax.swing.JTextField();
        disorderFileButton = new javax.swing.JButton();
        saveDisorderFileCheckBox = new javax.swing.JCheckBox();
        saveDisordeFileTextField = new javax.swing.JTextField();
        saveDisorderFileButton = new javax.swing.JButton();
        javax.swing.JPanel modelPanel = new javax.swing.JPanel();
        javax.swing.JPanel modelFilePanel = new javax.swing.JPanel();
        modelFileTextField = new javax.swing.JTextField();
        javax.swing.JPanel optionPanel = new javax.swing.JPanel();
        javax.swing.JButton optionBtn = new javax.swing.JButton();
        javax.swing.JPanel OKPanel = new javax.swing.JPanel();
        OKBtn = new javax.swing.JButton();
        javax.swing.JButton cancelBtn = new javax.swing.JButton();
        javax.swing.JPanel aatypePanel = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("PHOSIDE train");
        getContentPane().setLayout(new java.awt.GridBagLayout());

        xmlPanel.setLayout(new java.awt.GridBagLayout());

        xmlFilePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Training file in XML format"));
        xmlFilePanel.setMinimumSize(new java.awt.Dimension(400, 63));
        xmlFilePanel.setPreferredSize(new java.awt.Dimension(500, 63));
        xmlFilePanel.setLayout(new java.awt.GridBagLayout());

        trainXmlFilePanel.setLayout(new java.awt.GridBagLayout());

        trainXmlFileTextField.setToolTipText("Please select a FASTA training file");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        trainXmlFilePanel.add(trainXmlFileTextField, gridBagConstraints);

        trainXmlFileButton.setText("Open");
        trainXmlFileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                trainXmlFileButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        trainXmlFilePanel.add(trainXmlFileButton, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        xmlFilePanel.add(trainXmlFilePanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        xmlPanel.add(xmlFilePanel, gridBagConstraints);

        fileTypeTabbedPane.addTab("PHOSIDE XML", xmlPanel);

        fastaPanel.setLayout(new java.awt.GridBagLayout());

        fastaFilePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Training file in FASTA format"));
        fastaFilePanel.setMinimumSize(new java.awt.Dimension(400, 63));
        fastaFilePanel.setPreferredSize(new java.awt.Dimension(500, 63));
        fastaFilePanel.setLayout(new java.awt.GridBagLayout());

        trainFastaFilePanel.setLayout(new java.awt.GridBagLayout());

        trainFastaFileTextField.setToolTipText("Please select a FASTA training file");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        trainFastaFilePanel.add(trainFastaFileTextField, gridBagConstraints);

        trainFastaFileButton.setText("Open");
        trainFastaFileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                trainFastaFileButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        trainFastaFilePanel.add(trainFastaFileButton, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        fastaFilePanel.add(trainFastaFilePanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaPanel.add(fastaFilePanel, gridBagConstraints);

        disorderPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("File containing predicted disorder scores [optional]"));
        disorderPanel.setLayout(new java.awt.GridBagLayout());
        disorderPanel.setVisible(PhosideInit.trainingProps.getProperty(StaticFinalValues.USEDISORDERFEATURES).equalsIgnoreCase("true"));

        disorderFileCheckBox.setSelected(true);
        disorderFileCheckBox.setText("Disorder file:");
        disorderFileCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                disorderFileCheckBoxActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        disorderPanel.add(disorderFileCheckBox, gridBagConstraints);

        disordeFileTextField.setToolTipText("Please select file containing the disorder scores");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        disorderPanel.add(disordeFileTextField, gridBagConstraints);

        disorderFileButton.setText("Open");
        disorderFileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                disorderFileButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        disorderPanel.add(disorderFileButton, gridBagConstraints);

        saveDisorderFileCheckBox.setText("Save disorder result:");
        saveDisorderFileCheckBox.setEnabled(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        disorderPanel.add(saveDisorderFileCheckBox, gridBagConstraints);

        saveDisordeFileTextField.setToolTipText("Please select file to save the model");
        saveDisordeFileTextField.setEnabled(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        disorderPanel.add(saveDisordeFileTextField, gridBagConstraints);

        saveDisorderFileButton.setText("Open");
        saveDisorderFileButton.setEnabled(false);
        saveDisorderFileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveDisorderFileButtonActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        disorderPanel.add(saveDisorderFileButton, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        fastaPanel.add(disorderPanel, gridBagConstraints);

        fileTypeTabbedPane.addTab("FASTA", fastaPanel);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(fileTypeTabbedPane, gridBagConstraints);

        modelPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Output model name"));
        modelPanel.setLayout(new java.awt.GridBagLayout());

        modelFilePanel.setLayout(new java.awt.GridBagLayout());

        modelFileTextField.setToolTipText("Please specify the model name");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        modelFilePanel.add(modelFileTextField, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        modelPanel.add(modelFilePanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(modelPanel, gridBagConstraints);

        optionBtn.setText("Advanced options");
        optionBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                optionBtnActionPerformed(evt);
            }
        });
        optionPanel.add(optionBtn);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(optionPanel, gridBagConstraints);

        OKBtn.setText("   OK   ");
        OKBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                OKBtnActionPerformed(evt);
            }
        });
        OKPanel.add(OKBtn);

        cancelBtn.setText("Cancel");
        cancelBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelBtnActionPerformed(evt);
            }
        });
        OKPanel.add(cancelBtn);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(OKPanel, gridBagConstraints);

        aatypePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Types of sites"));
        aatypePanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 10, 5));

        aaTypeButtons = new LinkedHashMap();
        for (phoside.PhosphoProteins.PhosphoType phosphoType : phoside.PhosphoProteins.PhosphoType.values()) {
            javax.swing.JCheckBox cb = new javax.swing.JCheckBox(phosphoType.toString());
            aatypePanel.add(cb);
            aaTypeButtons.put(phosphoType, cb);
        }

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        getContentPane().add(aatypePanel, gridBagConstraints);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void optionBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optionBtnActionPerformed
        TrainingOptionDialog srcConfDialog = new TrainingOptionDialog(this, true);
        srcConfDialog.setLocationRelativeTo(this);
        srcConfDialog.setVisible(true);
        if (!srcConfDialog.isCancelled()) {
            disorderPanel.setVisible(PhosideInit.trainingProps.getProperty(StaticFinalValues.USEDISORDERFEATURES).equalsIgnoreCase("true"));
            this.pack();
        }
}//GEN-LAST:event_optionBtnActionPerformed

    private void cancelBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelBtnActionPerformed
        setVisible(false);
        dispose();
}//GEN-LAST:event_cancelBtnActionPerformed

    private void OKBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OKBtnActionPerformed
        if (!verifyInput())
            return;

        final cytoscape.task.ui.JTaskConfig jTaskConfig = new cytoscape.task.ui.JTaskConfig();
        jTaskConfig.setOwner(this.getParent());
        jTaskConfig.displayCloseButton(true);
        jTaskConfig.displayCancelButton(false);
        jTaskConfig.displayStatus(true);
        jTaskConfig.setAutoDispose(true);
        jTaskConfig.setMillisToPopup(100);

        //Reading phospho data
        PhosphoProteins phosphoData = new PhosphoProteinsImpl();
        ProteinsReader phosphoReader;
        switch(fileTypeTabbedPane.getSelectedIndex()) {
            case 0:
                phosphoReader = new PhosideXmlProteinsReader(
                        trainXmlFileTextField.getText(), phosphoData,
                        new PhosphoProteinFieldValueFormatter());
                break;
            case 1:
                try {
                   phosphoReader = new PhosphoReaderFromFastaWithSitesInSequence(
                           trainFastaFileTextField.getText(), phosphoData,
                           StaticFinalValues.DEFAULTHEADERRULE);
                } catch (IOException e) {
                    e.printStackTrace();
                    JOptionPane.showMessageDialog(this, "Failed to read the fasta file");
                    return;
                }
                break;
            default:
                return;
        }

        ProteinsReadTask phosphoReadTask = new ProteinsReadTask(phosphoReader);
        cytoscape.task.util.TaskManager.executeTask(phosphoReadTask, jTaskConfig);
        if (!phosphoReadTask.success()) {
            JOptionPane.showMessageDialog(this, "Failed to read the training file");
            return;
        }

        // predict disorder
        if (fileTypeTabbedPane.getSelectedIndex()==1) {
            boolean useDisorder = PhosideInit.trainingProps.getProperty(StaticFinalValues.USEDISORDERFEATURES).equalsIgnoreCase("true");
            if (useDisorder) {
                String dirDisorder = null;
                String dirDisSaveTo = null;
                if (useDisorder) {
                    boolean hasDisFile = disorderFileCheckBox.isSelected();
                    dirDisorder = hasDisFile ? disordeFileTextField.getText() : null;

                    boolean disSave = !hasDisFile & saveDisorderFileCheckBox.isSelected();
                    dirDisSaveTo = disSave ? saveDisordeFileTextField.getText() : null;
                }

                Map<String,List<Double>> mapDis = null;
                if (dirDisorder==null) {
                    DisorderPredictorVSL2 disorderPredictor = new DisorderPredictorVSL2();
                    DisorderPredictionTask disTask = new DisorderPredictionTask(phosphoData, disorderPredictor);
                    cytoscape.task.util.TaskManager.executeTask(disTask, jTaskConfig);
                    if (!disTask.success()) {
                        JOptionPane.showMessageDialog(this, "Failed to predict disorder");
                        return;
                    }

                    mapDis = disTask.getDisorder();

                    if (dirDisSaveTo!=null && mapDis!=null) {
                        DisorderInfoBatchWriter writer = new DisorderInfoBatchWriterFasta(dirDisSaveTo);
                        try {
                            writer.write(mapDis);
                        } catch (IOException ex) {
                            JOptionPane.showMessageDialog(this, "Failed to save the disorder information");
                            ex.printStackTrace();
                            return;
                        }
                    }
                } else {
                    DisorderReadTask readTask = new DisorderReadTask(dirDisorder);
                    cytoscape.task.util.TaskManager.executeTask(readTask, jTaskConfig);
                    if (!readTask.success()) {
                        JOptionPane.showMessageDialog(this, "Failed to read disorder");
                        return;
                    }

                    mapDis = readTask.getDisorder();
                }

                DisorderUtil.integrateDisorder(phosphoData, mapDis);
            }
        }

        // train
        //ModelParameter param = getModelParameter();
        Set<PhosphoProteins.PhosphoType> types = new LinkedHashSet();
        for (PhosphoProteins.PhosphoType type : aaTypeButtons.keySet()) {
            if (aaTypeButtons.get(type).isSelected()) {
                types.add(type);
            }
        }

        PhosideTrainTask trainTask = new PhosideTrainTask(phosphoData, types, PhosideInit.trainingProps);
        cytoscape.task.util.TaskManager.executeTask(trainTask, jTaskConfig);
        if (!trainTask.success()) {
            JOptionPane.showMessageDialog(this, "Failed to train the model.");
            return;
        }

        PhosideModel model = trainTask.getModel();
        if (model==null) {
            JOptionPane.showMessageDialog(this, "Failed to train the model.");
            return;
        }

        // save the model
        String dirModel = PhosideInit.modelDir.getAbsolutePath()+File.separator+modelFileTextField.getText();
        String format = "gz";
        SerializeTask serializeTask = new SerializeTask(new PhosideModel[]{model}, dirModel, format);
        cytoscape.task.util.TaskManager.executeTask(serializeTask, jTaskConfig);
        if (!serializeTask.success()) {
            JOptionPane.showMessageDialog(this, "Failed to save the model.");
            return;
        }
        
        succ = true;
        phoside.PhosideInit.initializeModels(); // load the model
        
        this.setVisible(false);
        this.dispose();

        JOptionPane.showMessageDialog(this, "Model trained successfully.");
}//GEN-LAST:event_OKBtnActionPerformed

    private void trainFastaFileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_trainFastaFileButtonActionPerformed
        JFileChooser fc = new JFileChooser(PhosideInit.defaultPath);
        ArrayList<String> exts = new ArrayList<String>(1);
        String ext = "fasta";
        exts.add(ext);
        fc.setFileFilter(new FileExtensionsFilter(exts,"Fasta file (.fasta)"));
        //fc.setAcceptAllFileFilterUsed(true);
        fc.setDialogTitle("Select a Fasta file...");
        int returnVal = fc.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            PhosideInit.defaultPath = file.getParent();

            String filePath = PhosideInit.defaultPath + File.separator + file.getName();
            trainFastaFileTextField.setText(filePath);

            String fileName = FilePathParser.getName(filePath);
            modelFileTextField.setText(fileName+"."+StaticFinalValues.MODELAPPEDIX);

            saveDisordeFileTextField.setText(PhosideInit.defaultPath+File.separator+fileName+"."+StaticFinalValues.DISORDERAPPENIX);
        }
    }//GEN-LAST:event_trainFastaFileButtonActionPerformed

    private void disorderFileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_disorderFileButtonActionPerformed
        JFileChooser fc = new JFileChooser(PhosideInit.defaultPath);
        ArrayList<String> exts = new ArrayList<String>(1);
        String ext = StaticFinalValues.DISORDERAPPENIX;
        exts.add(ext);
        fc.setFileFilter(new FileExtensionsFilter(exts,"Disorder file (.disorder)"));
        //fc.setAcceptAllFileFilterUsed(true);
        fc.setDialogTitle("Select a disorder file...");
        int returnVal = fc.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            PhosideInit.defaultPath = file.getParent();

            String filePath = PhosideInit.defaultPath + File.separator + file.getName();
            disordeFileTextField.setText(filePath);
        }
    }//GEN-LAST:event_disorderFileButtonActionPerformed

    private void saveDisorderFileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveDisorderFileButtonActionPerformed
        JFileChooser fc = new JFileChooser(PhosideInit.defaultPath);
        ArrayList<String> exts = new ArrayList<String>(1);
        String ext = "disorder";
        exts.add(ext);
        fc.setFileFilter(new FileExtensionsFilter(exts,"Disorder file (.disorder)"));
        //fc.setAcceptAllFileFilterUsed(true);
        fc.setDialogTitle("Save the the disorder scores to...");
        int returnVal = fc.showSaveDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            PhosideInit.defaultPath = file.getParent();

            String filePath = PhosideInit.defaultPath + File.separator + file.getName();
            saveDisordeFileTextField.setText(filePath);
        }
    }//GEN-LAST:event_saveDisorderFileButtonActionPerformed

    private void disorderFileCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_disorderFileCheckBoxActionPerformed
        if (disorderFileCheckBox.isSelected()) {
            disordeFileTextField.setEnabled(true);
            disorderFileButton.setEnabled(true);

            saveDisordeFileTextField.setEnabled(false);
            saveDisorderFileButton.setEnabled(false);
            saveDisorderFileCheckBox.setEnabled(false);
            saveDisorderFileCheckBox.setSelected(false);
        } else {
            disordeFileTextField.setEnabled(false);
            disorderFileButton.setEnabled(false);

            saveDisordeFileTextField.setEnabled(true);
            saveDisorderFileButton.setEnabled(true);
            saveDisorderFileCheckBox.setEnabled(true);
            saveDisorderFileCheckBox.setSelected(true);
        }
    }//GEN-LAST:event_disorderFileCheckBoxActionPerformed

    private void trainXmlFileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_trainXmlFileButtonActionPerformed
        JFileChooser fc = new JFileChooser(PhosideInit.defaultPath);
        ArrayList<String> exts = new ArrayList<String>(1);
        String ext = "xml";
        exts.add(ext);
        fc.setFileFilter(new FileExtensionsFilter(exts,"XML file (.xml)"));
        //fc.setAcceptAllFileFilterUsed(true);
        fc.setDialogTitle("Select a XML file...");
        int returnVal = fc.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            PhosideInit.defaultPath = file.getParent();

            String filePath = PhosideInit.defaultPath + File.separator + file.getName();
            trainXmlFileTextField.setText(filePath);

            String fileName = FilePathParser.getName(filePath);
            modelFileTextField.setText(fileName+"."+StaticFinalValues.MODELAPPEDIX);
        }
    }//GEN-LAST:event_trainXmlFileButtonActionPerformed

    private boolean verifyInput() {
        Set<PhosphoProteins.PhosphoType> types = new LinkedHashSet();
        for (PhosphoProteins.PhosphoType type : aaTypeButtons.keySet()) {
            if (aaTypeButtons.get(type).isSelected()) {
                types.add(type);
            }
        }

        if (types.isEmpty()) {
            JOptionPane.showMessageDialog(this, "Error: select at least one type of amino acid.");
            return false;
        }

        switch(fileTypeTabbedPane.getSelectedIndex()) {
            case 0:
                if (trainXmlFileTextField.getText().length()==0) {
                    JOptionPane.showMessageDialog(this, "Error: specify a XML file containing the protein sequences.");
                    return false;
                }
                break;
            case 1:
                String dirPhospho = trainFastaFileTextField.getText();
                if (dirPhospho.length()==0) {
                    JOptionPane.showMessageDialog(this, "Error: specify a FASTA file containing the protein sequences.");
                    return false;
                }

                boolean useDisorder = PhosideInit.trainingProps.getProperty(StaticFinalValues.USEDISORDERFEATURES).equalsIgnoreCase("true");

                String dirDisorder = null;
                String dirDisSaveTo = null;
                if (useDisorder) {
                    boolean hasDisFile = disorderFileCheckBox.isSelected();
                    dirDisorder = hasDisFile ? disordeFileTextField.getText() : null;
                    if (hasDisFile && (dirDisorder==null || dirDisorder.length()==0)) {
                        JOptionPane.showMessageDialog(this, "Error: specify a file containing disorder scores if you selected to use one.");
                        return false;
                    }

                    boolean disSave = !hasDisFile & saveDisorderFileCheckBox.isSelected();
                    dirDisSaveTo = disSave ? saveDisordeFileTextField.getText() : null;
                    if (disSave) {
                        if (dirDisSaveTo==null || dirDisSaveTo.length()==0) {
                            JOptionPane.showMessageDialog(this, "Error: specify a file to save the disorder result.");
                            return false;
                        } else if (phoside.util.IOUtil.fileExist(dirDisSaveTo)) {
                            int ret = JOptionPane.showConfirmDialog(this, "Are you sure to replace the existing disorder file?",
                                    null, JOptionPane.YES_NO_OPTION);
                            if (ret==JOptionPane.NO_OPTION) {
                                return false;
                            }
                        }
                    }
                }
                break;
            default:
                return false;
        }

        String dirModel = PhosideInit.modelDir.getAbsolutePath()+File.separator+modelFileTextField.getText();
        if (dirModel.length()==0) {
            JOptionPane.showMessageDialog(this, "Error: specify the model name.");
            return false;
        }

        if (phoside.util.IOUtil.fileExist(dirModel)) {
            int ret = JOptionPane.showConfirmDialog(this, "Are you sure to replace the existing model?",
                    null, JOptionPane.YES_NO_OPTION);
            if (ret==JOptionPane.NO_OPTION) {
                return false;
            }
        }

        return true;
    }

    public boolean success() {
        return succ;
    }

    private boolean succ = false;
    private Map<PhosphoProteins.PhosphoType, javax.swing.JCheckBox> aaTypeButtons;

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton OKBtn;
    private javax.swing.JTextField disordeFileTextField;
    private javax.swing.JButton disorderFileButton;
    private javax.swing.JCheckBox disorderFileCheckBox;
    private javax.swing.JPanel disorderPanel;
    private javax.swing.JPanel fastaPanel;
    private javax.swing.JTabbedPane fileTypeTabbedPane;
    private javax.swing.JTextField modelFileTextField;
    private javax.swing.JTextField saveDisordeFileTextField;
    private javax.swing.JButton saveDisorderFileButton;
    private javax.swing.JCheckBox saveDisorderFileCheckBox;
    private javax.swing.JTextField trainFastaFileTextField;
    private javax.swing.JTextField trainXmlFileTextField;
    private javax.swing.JPanel xmlPanel;
    // End of variables declaration//GEN-END:variables

}
